package com.tongguan.paypos.activity.menu;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.basewin.aidl.OnPrinterListener;
import com.basewin.define.FontsType;
import com.basewin.services.PrinterBinder;
import com.basewin.services.ServiceManager;
import com.tongguan.paypos.R;
import com.tongguan.paypos.base.BaseActivity;
import com.tongguan.paypos.base.MyApplication;
import com.tongguan.paypos.common.AppConstants;
import com.tongguan.paypos.common.CountTotal;
import com.tongguan.paypos.common.RequestCallback;
import com.tongguan.paypos.common.UrlConstants;
import com.tongguan.paypos.common.User;
import com.tongguan.paypos.entity.PayType;
import com.tongguan.paypos.entity.PayTypeInfo;
import com.tongguan.paypos.entity.SettleOrder;
import com.tongguan.paypos.entity.SettleResult;
import com.tongguan.paypos.entity.SettleTotal;
import com.tongguan.paypos.entity.Total;
import com.tongguan.paypos.utils.AppUtils;
import com.tongguan.paypos.utils.FileUtils;
import com.tongguan.paypos.utils.L;
import com.tongguan.paypos.utils.PrintUtils;
import com.tongguan.paypos.utils.ToastUtils;
import com.tongguan.paypos.view.CustomAlertDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public class TransSettleActivity extends BaseActivity {

    @BindView(R.id.tv_merchant_name)
    TextView mTvMerchantName;
    @BindView(R.id.tv_merchant_id)
    TextView mTvMerchantId;
    @BindView(R.id.tv_device_id)
    TextView mTvDeviceId;
    @BindView(R.id.tv_trans_success)
    TextView mTvTransSuccess;
    @BindView(R.id.tv_last_time)
    TextView mTvLastTime;
    @BindView(R.id.tv_this_time)
    TextView mTvThisTime;
    @BindView(R.id.tv_wx)
    TextView mTvWx;
    @BindView(R.id.ll_wx)
    LinearLayout mLlWx;
    @BindView(R.id.tv_zfb)
    TextView mTvZfb;
    @BindView(R.id.ll_zfb)
    LinearLayout mLlZfb;
    @BindView(R.id.tv_y)
    TextView mTvY;
    @BindView(R.id.ll_y)
    LinearLayout mLlY;
    @BindView(R.id.tv_cash)
    TextView mTvCash;
    @BindView(R.id.ll_cash)
    LinearLayout mLlCash;
    @BindView(R.id.tv_hyc)
    TextView mTvHyc;
    @BindView(R.id.ll_hyc)
    LinearLayout mLlHyc;
    @BindView(R.id.tv_qq)
    TextView mTvQq;
    @BindView(R.id.ll_qq)
    LinearLayout mLlQq;
    @BindView(R.id.tv_pos)
    TextView mTvPos;
    @BindView(R.id.ll_pos)
    LinearLayout mLlPos;
    @BindView(R.id.tv_jf)
    TextView mTvJf;
    @BindView(R.id.ll_jf)
    LinearLayout mLlJf;
    @BindView(R.id.tv_dk)
    TextView mTvDk;
    @BindView(R.id.ll_dk)
    LinearLayout mLlDk;
    @BindView(R.id.tv_wk)
    TextView mTvWk;
    @BindView(R.id.ll_wk)
    LinearLayout mLlWk;
    @BindView(R.id.tv_wallet)
    TextView mTvWallet;
    @BindView(R.id.ll_wallet)
    LinearLayout mLlWallet;
    @BindView(R.id.btn_settle)
    Button mBtnSettle;
    private static final int REQUEST_CODE_SETTLE_POS = 10100;
    public static final  String CACHE_NAME = "settle.json";

    private ArrayList<PayType> mPayTypes = new ArrayList<>();
    private List<Total> mTotals = new ArrayList<>();
    private List<SettleOrder> mSettleOrders = new ArrayList<>();
    private String lastTime, thisTime;
    private int index = 0;
    private boolean isSettle = true; //是否有结算数据
    private boolean isPosBills = false;//是否有刷卡流水
    private boolean isAgain = true;//手动结算时装
    private PrinterListener mPrinterListener = new PrinterListener();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_trans_settle);
        ButterKnife.bind(this);
        initTile(R.string.title_trans_settle, true);
        initView();
        loadSettle();
        loadPayType();
        initEvent();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.settle, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settle_pos:
                settlePos();
                isAgain = false;
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void initView() {
        mTvMerchantName.setText(User.getInstance().getMerchantName());
        mTvMerchantId.setText(User.getInstance().getMerchantId());
        mTvDeviceId.setText(User.getInstance().getPosId());
    }

    /**
     * 加载结算数据
     */
    public void loadSettle() {
        params = new HashMap<>();
        params.put(UrlConstants.KEY_ACCOUNT, User.getInstance().getAccount());
        params.put(UrlConstants.KEY_POS_ID, User.getInstance().getPosId());
        params.put(UrlConstants.KEY_SETTLEMENT, "0");
        RequestCallback.post(context, UrlConstants.TRANS_SETTLE, params, mDialog, new AbstractRequestCallback() {
            @Override
            public void onResponse(String response, int id) {
                SettleResult settleResult = SettleResult.objectFromData(response);
                if (settleResult.getStatus() != 100) {
                    ToastUtils.showCustom(context, settleResult.getMessage());
                    return;
                }
                lastTime = settleResult.getLastTime();
                thisTime = settleResult.getThisTime();
                List<SettleTotal> totalList = settleResult.getTotalList();
                if (totalList.size() > 0) {
                    mTotals = CountTotal.getCountTotal(totalList);
                } else {
                    ToastUtils.showCustom(context, "暂无结算数据");
                    setTimer(mHandler, 4);
                    isSettle = false;
                }
                updateView(mTotals);
                mSettleOrders = settleResult.getAllOrder();
            }
        });
    }

    /**
     * 加载支付方式
     */
    private void loadPayType() {
        if (MyApplication.getInstance().getPayTypes() == null) {
            params = new HashMap<>();
            params.put(UrlConstants.KEY_ACCOUNT, User.getInstance().getAccount());
            RequestCallback.post(context, UrlConstants.GET_PAY_TYPE, params, new AbstractRequestCallback() {
                @Override
                public void onResponse(String response, int id) {
                    PayTypeInfo payTypeInfo = PayTypeInfo.objectFromData(response);
                    if (payTypeInfo.getStatus() != 100) {
                        ToastUtils.showCustom(context, payTypeInfo.getMessage());
                        return;
                    }
                    List<PayTypeInfo.PayTypesBean> payTypes = payTypeInfo.getPayTypes();
                    if (payTypes == null || payTypes.size() == 0) {
                        ToastUtils.showCustom(context, "无支付方式");
                        return;
                    }
                    //固定支付方式
                    for (PayTypeInfo.PayTypesBean payType : payTypes) {
                        PayType data = AppConstants.payTypeMap.get(payType.getType());
                        if (data == null){
                            continue;
                        }
                        mPayTypes.add(data);
                    }
                    if (mPayTypes.size() == 0) {
                        L.d("支付方式不在本地中");
                        return;
                    }
                    if (MyApplication.getInstance().getPayTypes() == null) {
                        MyApplication.getInstance().setPayTypes(mPayTypes);
                    }
                    showView();
                }
            });
        } else {
            mPayTypes = MyApplication.getInstance().getPayTypes();
            showView();
        }
    }

    private void showView() { //只显示成功笔数
        if (mPayTypes.size() == 0) {
            return;
        }
        for (PayType payType : mPayTypes) {
            switch (payType.getId()) {
                case 0:
                    mLlWx.setVisibility(View.VISIBLE);
//                    mLlWxRevoke.setVisibility(View.VISIBLE);
                    break;
                case 1:
                    mLlZfb.setVisibility(View.VISIBLE);
//                    mLlZfbRevoke.setVisibility(View.VISIBLE);
                    break;
                case 2:
                    mLlY.setVisibility(View.VISIBLE);
//                    mLlYRevoke.setVisibility(View.VISIBLE);
                    break;
                case 3:
                    mLlCash.setVisibility(View.VISIBLE);
                    break;
                case 4:
                    mLlHyc.setVisibility(View.VISIBLE);
//                    mLlHykRevoke.setVisibility(View.VISIBLE);
                    break;
                case 5:
                    mLlQq.setVisibility(View.VISIBLE);
//                    mLlQqRevoke.setVisibility(View.VISIBLE);
                    break;
                case 6:
                    mLlPos.setVisibility(View.VISIBLE);
//                    mLlPosRevoke.setVisibility(View.VISIBLE);
                    break;
                case 7:
                    mLlJf.setVisibility(View.VISIBLE);
                    break;
                case 8:
                    mLlDk.setVisibility(View.VISIBLE);
                    break;
                case 9:
                    mLlWk.setVisibility(View.VISIBLE);
//                    mLlWkRevoke.setVisibility(View.VISIBLE);
                    break;
                case 10:
                    mLlWallet.setVisibility(View.VISIBLE);
                    break;
            }
        }
    }

    private void updateView(List<Total> countTotal) {
        mTvLastTime.setText(lastTime);
        mTvThisTime.setText(thisTime);
        for (Total total : countTotal) {
            String type = total.getType();
            if ("wx".equals(type)) {
                mTvWx.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("zfb".equals(type)) {
                mTvZfb.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("yzf".equals(type)) {
                mTvY.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("xj".equals(type)) {
                mTvCash.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("hyc".equals(type)) {
                mTvHyc.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("qq".equals(type)) {
                mTvQq.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("pos".equals(type)) {
                isPosBills = true;
                mTvPos.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("jf".equals(type)) {
                mTvJf.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("dk".equals(type)) {
                mTvDk.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("xl".equals(type)) {
                mTvWk.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            } else if ("ylsm".equals(type)) {
                mTvWallet.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            }else if ("total".equals(type)) {
                mTvTransSuccess.setText(total.getSuccessNum() + "笔，共计" + total.getSuccessMoney() + "元");
            }
        }
    }

    private void initEvent() {
        mBtnSettle.setOnClickListener(v -> {
            if (isSettle) {
                new CustomAlertDialog.Builder(context).setTitle(R.string.common_tip_title)
                        .setMessage("是否批结算？")
                        .setPositiveButton(R.string.common_sure, (dialog, which) -> {
                            settle();
                        }).setNegativeButton(R.string.common_cancel, (dialog, which) -> {
                }).show();
            } else {
                ToastUtils.showCustom(context, "暂无结算数据");
            }
        });
    }

    /**
     * 结算
     */
    private void settle() {
        params = new HashMap<>();
        params.put(UrlConstants.KEY_ACCOUNT, User.getInstance().getAccount());
        params.put(UrlConstants.KEY_POS_ID, User.getInstance().getPosId());
        params.put(UrlConstants.KEY_SETTLEMENT, "1");
        RequestCallback.post(context, UrlConstants.TRANS_SETTLE, params, mDialog, new AbstractRequestCallback() {
            @Override
            public void onResponse(String response, int id) {
                SettleResult settleResult = SettleResult.objectFromData(response);
                if (settleResult.getStatus() != 100) {
                    ToastUtils.showCustom(context, settleResult.getMessage());
                    return;
                }
                cacheJsonData(response);
                if (!mDialog.isShowing()) {
                    mDialog.setLoadingMessage("打印中...");
                    mDialog.show();
                }
                mHandler.sendEmptyMessageDelayed(0, 500);
            }
        });
    }

    private void settlePos() {
        Bundle bundle = new Bundle();
        bundle.putString("transName", "结算");
        AppUtils.runComponent(TransSettleActivity.this, AppConstants.UNION_PAY_APP_PACKAGE, AppConstants.SETTLEMENT_DIR, bundle, REQUEST_CODE_SETTLE_POS);
    }

    /**
     * 打印结算
     */
    private void printerTotal() {
        new Thread(() -> {
            try {
                PrinterBinder printer = ServiceManager.getInstence().getPrinter();
                printer.setPrintGray(1500);
                printer.setPrintFont(FontsType.simsun);
                printer.cleanCache();
                String data = PrintUtils.printSettleTotal(mTotals, lastTime, thisTime,false);
                mPrinterListener.isRepeat = false;
                printer.print(data,null,mPrinterListener);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 打印明细
     */
    private void printerDetails() {
        new Thread(() -> {
            try {
                PrinterBinder printer = ServiceManager.getInstence().getPrinter();
                printer.setPrintGray(1500);
                printer.setPrintFont(FontsType.simsun);
                printer.cleanCache();
                String data = PrintUtils.printSettleOrder(mSettleOrders);
                mPrinterListener.isRepeat = false;
                printer.print(data,null,mPrinterListener);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (!isFinishing()) {
                switch (msg.what) {
                    case 0:
                        if (mTotals.size() <= 0) {
                            ToastUtils.showCustom(context, "没有数据，无法打印");
                            return;
                        }
                        printerTotal();
                        break;
                    case 1:
                        if (mDialog != null && mDialog.isShowing()) {
                            mDialog.dismiss();
                        }
                        if (index == 0) {
                            new CustomAlertDialog.Builder(context).setTitle(R.string.common_tip_title)
                                    .setMessage("是否打印明细")
                                    .setPositiveButton("确定打印", (dialog, which) -> {
                                        if (mDialog != null && !mDialog.isShowing()) {
                                            mDialog.show();
                                        }
                                        index++;
                                        if (mSettleOrders.size() <= 0) {
                                            ToastUtils.showCustom(context, "明细没有数据，无法打印");
                                            mHandler.sendEmptyMessage(3);
                                            return;
                                        }
                                        printerDetails();
                                    }).setNegativeButton("退出打印", (dialog, which) -> mHandler.sendEmptyMessage(3)).show();//
                        }else  if (index == 1) { //重打印
                            mHandler.sendEmptyMessage(3);
                            index = 0;
                        }
                        break;
                    case 2: //打印异常重打印
                        if (mDialog != null && mDialog.isShowing()) {
                            mDialog.dismiss();
                        }
                        index = 0;//错误后全部重新打印
                        String message = (String) msg.obj;
                        new CustomAlertDialog.Builder(context).setTitle(R.string.common_tip_title)
                                .setMessage("异常 " + message)
                                .setPositiveButton("重新打印", (dialog, which) -> {
                                    if (mDialog != null && !mDialog.isShowing()) {
                                        mDialog.show();
                                    }
                                    mHandler.sendEmptyMessage(0);
                                }).setNegativeButton("退出", (dialog, which) -> mHandler.sendEmptyMessage(3)).show();
                        break;
                    case 3://其它结算
                        if (mDialog != null && mDialog.isShowing()) {
                            mDialog.dismiss();
                        }
                        isAgain = true;
                        // 同时批结算银联
                        if (isPosBills) {//是否有银联流水
                            settlePos();
                        } else {
                            setTimer(mHandler, 4);
                        }
                        break;
                    case 4:
                        //不能再结算
                        mBtnSettle.setEnabled(false);
                        int m = (Integer) msg.obj;
                        mBtnSettle.setText("结 算" + " (" + m / 1000 + ")");
                        if (m / 1000 == 0) {
                            mTime.cancel();
                            finish();
                        }
                        break;
                }
            }
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        L.d("requestCode = " + requestCode + " resultCode = " + resultCode);
            if (requestCode == REQUEST_CODE_SETTLE_POS) {
                if (resultCode == Activity.RESULT_OK) {
                    ToastUtils.showCustom(context, "结算成功");
                    if (isAgain) {
                        setTimer(mHandler, 4);
                    }
                } else {
                    if (isAgain) {
                        setTimer(mHandler, 4);
                    }
                }
            }
    }

    private void cacheJsonData(String data){
        new Thread(() -> {
            FileUtils.writeFile(AppConstants.CACHE_DIR+ CACHE_NAME,data,false);
            L.d("缓存批结算数据成功");
        }).start();
    }

    private class PrinterListener implements OnPrinterListener{
        boolean isRepeat = false;
        @Override
        public void onStart() {
            // TODO 打印开始
            L.d(" 打印开始");
        }

        @Override
        public void onFinish() {
            // TODO 打印结束
            L.d(" 打印结束");
            mHandler.sendEmptyMessage(1);
        }

        @Override
        public void onError(int errorCode, String detail) {
            // TODO 打印出错
            L.d(" 打印出错");
            if (!isRepeat) {
                isRepeat = true;
                if (errorCode == PrinterBinder.PRINTER_ERROR_NO_PAPER) {
                    mHandler.sendMessage(mHandler.obtainMessage(2, detail));
                } else {
                    ToastUtils.showCustom(context, detail + "--" + errorCode);
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        RequestCallback.cancelAllRequest();
    }
}
